#pragma once

#include "mp3types.h"

class CBitReserve
{
	uint32 offset, totbit;
	uint32 buf_bit_idx, buf_byte_idx;

	uint32 buf[4096];
	uint32 putmask[32];

public:
	CBitReserve();
	~CBitReserve() {};

	uint32 hsstell() const { return totbit; }
	uint32 hgetbits(uint32 N);
	uint32 hget1bit();
	void hputbuf(int32 val);

	void rewindNbits(int32 N);
	void rewindNbytes(int32 N);
};

const int BufferSize = 4096;

inline CBitReserve::CBitReserve() : offset(0), totbit(0), buf_byte_idx(0), buf_bit_idx(8)
{
	*putmask = 0;
	uint32 shifted_one = 1;
	for (int32 i = 1; i < 32; i++)
	{
		putmask[i] = putmask[i-1] + shifted_one;
		shifted_one <<= 1;
	}
};

// write 8 bits into the bit stream
inline void CBitReserve::hputbuf(int32 val)
{
	buf[offset] = val;
	offset = (offset + 1) & 0xfff;
};

inline void CBitReserve::rewindNbytes(int32 N)
{
	totbit -= (N << 3);
	buf_byte_idx -= N;
};

inline void CBitReserve::rewindNbits(int32 N)
{
	totbit -= N;
	buf_bit_idx += N;
	while (buf_bit_idx >= 8)
	{
		buf_bit_idx -= 8;
		buf_byte_idx--;
	}
};
